#include "EpilUnaryExpressionCode.h"
#include "EpilOutputHelper.h"
#include "TCharSupport.h"
#include "EpilBinaryExpressionCode.h"
#include "EpilPointerHelper.h"


EpilUnaryExpressionCode::EpilUnaryExpressionCode( const EpilLexLocation & location )
: EpilExpressionCodeBase( location )
, m_expression( NULL )
{
}


EpilUnaryExpressionCode::~EpilUnaryExpressionCode()
{
	EpilPointerHelper::SafeDelete( m_expression );
}


tstring EpilUnaryExpressionCode::ToEpilCode( int indent ) const
{
	tstringstream ret;
	int precedence = EpilOutputHelper::GetUnaryOperatorPrecedence( m_operator );

	ret << EpilOutputHelper::GetUnaryOperator( m_operator );
	if( m_operator == EUO_Not )
	{
		ret << t(" ");
	}

	bool isNeedParentheses = false;
	if( m_expression->GetType() == ECT_BinaryExpression )
	{
		EpilBinaryExpressionCode * binary = static_cast<EpilBinaryExpressionCode*>( m_expression );
		int subPrecedence = EpilOutputHelper::GetBinaryOperatorPrecedence( binary->GetOperator() );
		if( subPrecedence < precedence )
		{
			isNeedParentheses = true;
		}
	}
	else if( m_expression->GetType() == ECT_UnaryExpression )
	{
		EpilUnaryExpressionCode * unary = static_cast<EpilUnaryExpressionCode*>( m_expression );
		int subPrecedence = EpilOutputHelper::GetUnaryOperatorPrecedence( unary->GetOperator() );
		if( subPrecedence < precedence )
		{
			isNeedParentheses = true;
		}
	}
	if( isNeedParentheses )
	{
		ret << t("( ");
		ret << m_expression->ToEpilCode();
		ret << t(" )");
	}
	else
	{
		ret << m_expression->ToEpilCode();
	}
	return ret.str();
}